home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.02 Feb 89 / security code / MainDlog.p < prev    next >
Encoding:
Text File  |  1988-11-29  |  8.0 KB  |  322 lines  |  [TEXT/MPS ]

  1. UNIT  MainDlog;
  2. {-------------------------------------------}
  3. (*
  4. ©1988 by Steve Seaquist. All rights reserved.
  5. Used by permission.  Use at your own risk.  
  6. No warranty is expressed or implied.  
  7.  
  8. This Macintosh virus-detecting program was 
  9. originally published and explained in the 
  10. February 1989 issue of MacTutor magazine.  
  11. Some aspects of its design are important to 
  12. security, and it uses some unusual 
  13. techniques, so please read the article.  
  14. *)
  15. {-------------------------------------------}
  16. INTERFACE
  17. USES
  18.   MemTypes,QuickDraw,OSIntf,ToolIntf,
  19.   PackIntf,Globals;
  20.  
  21. PROCEDURE  InitMainDlog;
  22. FUNCTION   MainDlogWorkRequested
  23.   :          TMainItem;
  24.  
  25. {*******************************************}
  26. IMPLEMENTATION
  27. {$R-}
  28.  
  29. CONST
  30.   {--------item range--------}
  31.   kItemFst            = eDirs;
  32.   kItemLst            = eDBtn;
  33.   {----item type subranges---}
  34.   kBtnFst             = eDirs;
  35.   kBtnLst             = eQuit;
  36.   kChkFst             = eAwait;
  37.   kChkLst             = eTrace;
  38.   kStatFst            = eMain;
  39.   kStatLst            = eScOW;
  40.   kUItmFst            = eDBtn;
  41.   kUItmLst            = eDBtn;
  42.   {---titled item subrange---}
  43.   kTItmFst            = eDirs;
  44.   kTItmLst            = eScOW;
  45.  
  46. TYPE
  47.   TDitmPtr            = ^TDitmRec;
  48.   TDitmRec            =
  49.     PACKED RECORD
  50.     fProcPtr:         ProcPtr;
  51.     fRect:            Rect;
  52.     fType:            Byte;
  53.     fLen:             Byte;
  54.     fData:            INTEGER;
  55.     END;
  56.  
  57. VAR
  58.   gDBtnRect:          Rect;
  59.   gHdl:               ARRAY [eAwait..eTrace]
  60.                       OF ControlHandle;
  61.   gRect:              ARRAY [eAwait..eTrace]
  62.                       OF Rect;
  63.  
  64. {-------------------------------------------}
  65. PROCEDURE  ChkChk
  66.   (pItem:    TMainItem);
  67. BEGIN
  68. IF  (pItem < kChkFst)
  69. OR  (pItem > kChkLst) THEN
  70.   BEGIN
  71.   SysBeep(3);
  72.   EXIT(ChkChk);
  73.   END;
  74. SetCtlValue(gHdl[pItem],ORD(gOption[pItem]));
  75. IF  gDisabled[pItem] THEN
  76.   BEGIN
  77.   SetDItem(gDlogPtr,ORD(pItem),
  78.     ctrlItem+chkCtrl+itemDisable,
  79.     Handle(gHdl[pItem]),gRect[pItem]);
  80.   HiliteControl(gHdl[pItem],255);
  81.   END
  82. ELSE
  83.   BEGIN
  84.   SetDItem(gDlogPtr,ORD(pItem),
  85.     ctrlItem+chkCtrl,
  86.     Handle(gHdl[pItem]),gRect[pItem]);
  87.   HiliteControl(gHdl[pItem],0);
  88.   END;
  89. END;
  90. {-------------------------------------------}
  91. PROCEDURE  FrameDefaultBtn
  92.   (pWindowPtr:WindowPtr;
  93.   pItemNo:   INTEGER);
  94. VAR
  95.   sPenState: PenState;
  96. BEGIN
  97. GetPenState(sPenState);
  98. PenSize (3,3);
  99. FrameRoundRect(gDBtnRect,16,16);
  100. SetPenState(sPenState);
  101. END;
  102. {-------------------------------------------}
  103. PROCEDURE  InitMainDlog;
  104. CONST
  105.   kTitleMax       = 27;
  106.   kTItmLen        = 42;
  107.     { 14 + kTitleMax + ord(odd(kTitleMax)); }
  108.   kUItmLen        = 14;
  109. VAR
  110.   i:              TMainItem;
  111.   sDitmPtr:       TDitmPtr;
  112.   sDlogRect:      Rect;
  113.   sHdl:           Handle;
  114.   sNbrTItms:      INTEGER;
  115.   sNbrUItms:      INTEGER;
  116.   sRect:          ARRAY [eDirs..eScOW]
  117.                   OF Rect;
  118.   sSize:          Size;
  119.   sTitle:         ARRAY [eDirs..eScOW]
  120.                   OF STRING[kTitleMax];
  121.   sType:          INTEGER;
  122. BEGIN
  123. IF  gOption[eTrace] THEN
  124.   Trace('InitMainDlog');
  125. FOR i := kTItmFst TO kTItmLst DO
  126.   IF  (i >= kBtnFst)
  127.   AND (i <= kBtnLst) THEN
  128.     BEGIN
  129.     SetRect   (sRect[i], 266, 65, 346, 83);
  130.     OffsetRect(sRect[i],0,
  131.               27*(ORD(i)-ORD(kBtnFst)));
  132.     END
  133.   ELSE IF (i >= kChkFst)
  134.   AND     (i <= kChkLst) THEN
  135.     BEGIN
  136.     SetRect   (sRect[i],  24, 62, 185, 80);
  137.     OffsetRect(sRect[i],0,
  138.               20*(ORD(i)-ORD(kChkFst)));
  139.     END
  140.   ELSE
  141.     SetRect   (sRect[i],  12, 42, 216, 60);
  142. OffsetRect(sRect[eMain], 080,-30);
  143. OffsetRect(sRect[eOpts], 000,000);
  144. OffsetRect(sRect[eScOW], 216,000);
  145.  
  146. gDBtnRect := sRect[kItemFst];
  147. InsetRect (gDBtnRect, -4, -4);
  148.  
  149. WITH sDlogRect, gSFGetPt DO
  150.   BEGIN
  151.   top    := v - 10;
  152.   left   := h - 10;
  153.   bottom := top  + 210;
  154.   right  := left + 368;
  155.   END;
  156.  
  157. sTitle[eDirs]  := 'Directories';
  158. sTitle[eDiry]  := 'Directory';
  159. sTitle[eEvery] := 'Everything';
  160. sTitle[eFiles] := 'Files';
  161. sTitle[eQuit]  := 'Quit';
  162. sTitle[eAwait] := 'Await Keypress';
  163. sTitle[eBeeps] := 'Beep';
  164. sTitle[eFgPr]  := 'Fingerprint';
  165. sTitle[eFgPrC] := 'Fingerprint CODEs';
  166. sTitle[eLList] := 'Long Listing';
  167. sTitle[eRmVir] := 'Remove Viruses';
  168. sTitle[eTrace] := 'Trace';
  169. sTitle[eMain]  := 
  170.   'Security Patrol Main Dialog';
  171. sTitle[eOpts]  := 'Options:';
  172. sTitle[eScOW]  := 'Scope Of Work:';
  173.  
  174. sNbrTItms := (ORD(kTItmLst)-ORD(kTItmFst))+1;
  175. sNbrUItms := (ORD(kUItmLst)-ORD(kUItmFst))+1;
  176. sHdl := NewHandle(2 + (sNbrTItms*kTItmLen)
  177.                     + (sNbrUItms*kUItmLen));
  178. TWordPtr(sHdl^)^ := ORD(kItemLst) - 1;
  179. sSize := 2;
  180. FOR i := kItemFst TO kItemLst DO
  181.   BEGIN
  182.   IF  gOption[eTrace] THEN
  183.     TraceNbr('sSize = ',sSize);
  184.   sDitmPtr := POINTER(ORD4(sHdl^)+sSize);
  185.   WITH sDitmPtr^ DO
  186.     IF  (i >= kTItmFst)
  187.     AND (i <= kTItmLst) THEN
  188.       BEGIN
  189.       fProcPtr := NIL;
  190.       fRect    := sRect[i];
  191.       IF  (i <= kBtnLst) THEN
  192.         fType  := ctrlItem + btnCtrl
  193.       ELSE IF  (i <= kChkLst) THEN
  194.         fType  := ctrlItem + chkCtrl
  195.       ELSE
  196.         fType  := statText + itemDisable;
  197.       BlockMove(@sTitle[i],@fLen,
  198.                 LENGTH(sTitle[i])+1);
  199.       sSize := sSize+14+fLen+ORD(ODD(fLen));
  200.       END
  201.     ELSE IF  (i = eDBtn) THEN
  202.       BEGIN
  203.       fProcPtr := @FrameDefaultBtn;
  204.       fRect    := gDBtnRect;
  205.       fType    := userItem + itemDisable;
  206.       fLen     := 0;
  207.       sSize    := sSize + 14;
  208.       END
  209.     ELSE
  210.       SysBeep(60);
  211.   END;
  212. SetHandleSize(sHdl,sSize);
  213. gDlogPtr := NewDialog(NIL,sDlogRect,'',
  214.   FALSE,dBoxProc,POINTER(-1),FALSE,0,sHdl);
  215. FOR i := kChkFst TO kChkLst DO
  216.   BEGIN
  217.   GetDItem(gDlogPtr,ORD(i),sType,
  218.            Handle(gHdl[i]),gRect[i]);
  219.   IF  gOption[eTrace] THEN
  220.     TraceNbr('ChkChk’ing item ',ORD(i));
  221.   ChkChk(i);
  222.   END;
  223. END;
  224. {-------------------------------------------}
  225. FUNCTION   KybdEquivsFilter
  226.   (pDialogPtr:   DialogPtr;
  227.   VAR pEventRec: EventRecord;
  228.   VAR pItemHit:  INTEGER)
  229.   :              BOOLEAN;
  230. VAR
  231.   sChar:
  232.     RECORD
  233.     CASE INTEGER OF
  234.     0:(F1,F2,F3: SignedByte;
  235.        Enum:     TMainItem);
  236.     1:(L:        LONGINT);
  237.     END;
  238.   sItem:         TMainItem;
  239. BEGIN
  240. sItem := eNotADlogItem;
  241. WITH pEventRec DO
  242.   IF  (what = keyDown) THEN
  243.     BEGIN
  244.     sChar.L := BAnd(message,charCodeMask);
  245.     IF  (sChar.L = $03) 
  246.     OR  (sChar.L = $0D) THEN
  247.       sItem := eDirs
  248.     ELSE IF (sChar.L = ORD('D')) 
  249.     OR      (sChar.L = ORD('d')) THEN
  250.       sItem := eDiry
  251.     ELSE IF (sChar.L = ORD('E')) 
  252.     OR      (sChar.L = ORD('e')) THEN
  253.       sItem := eEvery
  254.     ELSE IF (sChar.L = ORD('F')) 
  255.     OR      (sChar.L = ORD('f')) THEN
  256.       sItem := eFiles
  257.     ELSE IF (sChar.L = ORD('Q')) 
  258.     OR      (sChar.L = ORD('q')) 
  259.     OR ((BAnd(modifiers,cmdKey)<>0) 
  260.         AND (sChar.L = ORD('.'))) THEN
  261.       sItem := eQuit
  262.     ELSE
  263.       BEGIN
  264.       sChar.L := 
  265.         (sChar.L-ORD4('1')) + ORD(kChkFst);
  266.       IF  (sChar.L >= ORD(kChkFst)) 
  267.       AND (sChar.L <= ORD(kChkLst)) THEN
  268.         IF  NOT(gDisabled[sChar.Enum]) THEN
  269.           sItem := sChar.Enum;
  270.       END;
  271.     END;
  272. IF  (sItem = eNotADlogItem) THEN
  273.   KybdEquivsFilter := FALSE
  274. ELSE
  275.   BEGIN
  276.   pItemHit         := ORD(sItem);
  277.   KybdEquivsFilter := TRUE;
  278.   END;
  279. END;
  280. {-------------------------------------------}
  281. FUNCTION   MainDlogWorkRequested
  282.   :          TMainItem;
  283. VAR
  284.   sItem:
  285.     RECORD
  286.     CASE INTEGER OF
  287.     0:(Filler: SignedByte;
  288.        Enum:   TMainItem);
  289.     1:(Int:    INTEGER);
  290.     END;
  291. BEGIN
  292. IF  gOption[eTrace] THEN
  293.   Trace('MainDlogWorkRequested');
  294. BringToFront(gDlogPtr);
  295. ShowWindow  (gDlogPtr);
  296. ModalDialog (@KybdEquivsFilter,sItem.Int);
  297. WHILE (sItem.Enum >= kChkFst)
  298. AND   (sItem.Enum <= kChkLst) DO
  299.   BEGIN
  300.   gOption[sItem.Enum] := 
  301.     NOT(gOption[sItem.Enum]);
  302.   ChkChk(sItem.Enum);
  303.   IF  (sItem.Enum = eFgPr) THEN
  304.     BEGIN
  305.     gDisabled[eFgPrC] := NOT(gOption[eFgPr]);
  306.     gOption  [eFgPrC] := FALSE;
  307.     ChkChk(eFgPrC);
  308.     END;
  309.   ModalDialog (@KybdEquivsFilter,sItem.Int);
  310.   END;
  311. HideWindow  (gDlogPtr);
  312. SetPort     (gGrafPtr);
  313. IF  gOption[eTrace] THEN
  314.   TraceNbr('Returning ',ORD(sItem.Enum));
  315. IF  (sItem.Enum >= kItemFst)
  316. AND (sItem.Enum <= kItemLst) THEN
  317.   MainDlogWorkRequested := sItem.Enum
  318. ELSE
  319.   MainDlogWorkRequested := eQuit;
  320. END;
  321. {*******************************************}
  322. END.